package agency.refunds ;

import java.util.Date ;
import java.util.Map ;
import java.util.Objects ;
import java.util.Properties ;
import java.util.TreeMap ;

import com.cybersource.ws.client.Client ;

import agency.Refunds ;
import dict.AgencyDict ;
import dict.CbDict ;
import entities.TBank ;
import entities.TCard ;
import entities.TCb ;
import entities.TTransaction ;
import util.LogUtil ;
import utils.DateUtil ;
import utils.NumberUtil ;
import utils.StringUtil ;

public class Cbyedc implements Refunds
{

	private static String CURRENCY = "CNY" ;

	private static String keysDirectory = "d:\\" ;

	static
	{
		if ( "linux".equalsIgnoreCase ( System.getProperty ( "os.name" ) ) )
		{
			keysDirectory = "/usr/local/tomcat9/" ;
		} else
		{
			keysDirectory = "d:\\" ;
		}
	}

	private static String targetAPIVersion = "1.158" ;

	private static String numberOfRetries = "5" ;

	private static String retryInterval = "5" ;

	@SuppressWarnings ( "unchecked" )
	public void process (
			TCb cb ,
			TTransaction transaction ,
			TBank bank ,
			TCard card
	)
	{
		// TODO Auto-generated method stub
		Map < String , String > requestMap = new TreeMap < String , String > ( ) ;
		Map < String , String > responseMap = new TreeMap < String , String > ( ) ;

		// 配置
		Properties cybsInfo = new Properties ( ) ;
		cybsInfo.put ( "merchantID" , bank.getBnkMer ( ) ) ;
		cybsInfo.put ( "keysDirectory" , keysDirectory ) ;
		cybsInfo.put ( "keyAlias" , bank.getBnkMer ( ) ) ;
		cybsInfo.put ( "keyPassword" , bank.getBnkMer ( ) ) ;
		cybsInfo.put ( "targetAPIVersion" , targetAPIVersion ) ;
		cybsInfo.put ( "sendToProduction" , "true" ) ;
		cybsInfo.put ( "sendToAkamai" , "true" ) ;
		cybsInfo.put ( "useHttpClient" , "false" ) ;
		cybsInfo.put ( "allowRetry" , "true" ) ;
		cybsInfo.put ( "numberOfRetries" , numberOfRetries ) ;
		cybsInfo.put ( "retryInterval" , retryInterval ) ;
		cybsInfo.put ( "enableJdkCert" , "false" ) ;
		cybsInfo.put ( "enableCacert" , "false" ) ;
		cybsInfo.put ( "cacertPassword" , "" ) ;
		cybsInfo.put ( "useSignAndEncrypted" , "false" ) ;
		cybsInfo.put ( "timeout" , "1000" ) ;
		cybsInfo.put ( "enableLog" , "false" ) ;
		cybsInfo.put ( "logMaximumSize" , "10" ) ;
		cybsInfo.put ( "certificateCacheEnabled" , "true" ) ;

		// 退款

		requestMap.put ( "ccCreditService_run" , "true" ) ;
		requestMap.put ( "merchantReferenceCode" , cb.getCbNo ( ) ) ;
		requestMap.put ( "ccCreditService_captureRequestID" , cb.getCbRef ( ) ) ;
		requestMap.put ( "purchaseTotals_currency" , CURRENCY ) ;
		requestMap.put ( "item_0_unitPrice" , NumberUtil.transfer ( cb.getCbAmount ( ) ) ) ;


		// 日志打印发送数据
		StringBuffer send = new StringBuffer ( ) ;
		for ( Map.Entry < String , String > e : requestMap.entrySet ( ) )
		{
			send.append ( e.getKey ( ) + "=" + e.getValue ( ) + "&" ) ;
		}
		LogUtil.agency ( "CBYEDC_REFUND" , send.toString ( ) ) ;

		try
		{
			responseMap = Client.runTransaction ( requestMap , cybsInfo ) ;
		} catch ( Exception ex )
		{
			try
			{
				Thread.sleep ( 3000 );
				responseMap = Client.runTransaction ( requestMap , cybsInfo ) ;
			} catch ( Exception e )
			{
				e.printStackTrace ( );
				cb.setCbMark ( "555" ) ;
				cb.setCbInfo ( "edc refund data encrpt exception" ) ;
				cb.setCbCode ( AgencyDict.CBY_TRANSMISSION_EXCEPTION ) ;
				cb.setCbMessage ( AgencyDict.AGENCY.get ( AgencyDict.CBY_TRANSMISSION_EXCEPTION ) ) ;
				return ;
			}
		}

		if ( Objects.isNull ( responseMap ) )
		{
			cb.setCbMark ( "555" ) ;
			cb.setCbInfo ( "edc refund data response exception" ) ;
			cb.setCbCode ( AgencyDict.CBY_TRANSMISSION_EXCEPTION ) ;
			cb.setCbMessage ( AgencyDict.AGENCY.get ( AgencyDict.CBY_TRANSMISSION_EXCEPTION ) ) ;
			return ;
		}

		// 日志打印返回数据
		StringBuffer reve = new StringBuffer ( ) ;
		for ( Map.Entry < String , String > e : responseMap.entrySet ( ) )
		{
			reve.append ( e.getKey ( ) + "=" + e.getValue ( ) + "&" ) ;
		}
		LogUtil.agency ( "CBYEDC_REFUND" , reve.toString ( ) ) ;

		if ( ! responseMap.containsKey ( "reasonCode" ) )
		{
			cb.setCbMark ( "555" ) ;
			cb.setCbInfo ( "edc sale data parameter exception" ) ;
			cb.setCbCode ( AgencyDict.CBY_TRANSMISSION_EXCEPTION ) ;
			cb.setCbMessage ( AgencyDict.AGENCY.get ( AgencyDict.CBY_TRANSMISSION_EXCEPTION ) ) ;
			return ;
		}

		if ( ! responseMap.get ( "reasonCode" ).equals ( "100" ) )
		{
			cb.setCbMark ( StringUtil.space ( responseMap.get ( "reasonCode" ) ) ) ;
			cb.setCbInfo ( StringUtil.space ( responseMap.get ( "reasonCode" ) ) + StringUtil.quote ( responseMap.get ( "decision" ) ) ) ;
			cb.setCbCode ( AgencyDict.CBY_REFUND_FAILURE ) ;
			cb.setCbMessage ( AgencyDict.AGENCY.get ( AgencyDict.CBY_REFUND_FAILURE ) ) ;
			return ;
		}

		cb.setCbState ( "1" ) ;
		cb.setCbRef ( responseMap.get ( "requestID" ) ) ;
		cb.setCbCard ( card.getCrdFake ( ) ) ;
		cb.setCbTime ( DateUtil.format ( new Date ( ) , DateUtil.DATE ) ) ;
		cb.setCbMark ( StringUtil.space ( responseMap.get ( "reasonCode" ) ) ) ;
		cb.setCbInfo ( StringUtil.space ( responseMap.get ( "reasonCode" ) ) + StringUtil.quote ( responseMap.get ( "decision" ) ) ) ;
		cb.setCbCode ( CbDict.CB_SUCCESS ) ;
		cb.setCbMessage ( CbDict.MESSAGES.get ( CbDict.CB_SUCCESS ) ) ;
		return ;
	}

}
